晓晓的个人博客Logo
晓晓的个人博客
Chrome Extension 和 Puppeteer 如何获取 closed 状态的 Shadow Root
AI提炼icon
提炼
Shadow Root 有 open 和 closed 两种状态,以在封装性和可访问性间提供不同权衡。标准规范中,closed 状态的 Shadow Root 初始化后无法改为 open,也不能用 element.shadowRoot 直接访问。如在示例的 my - component 组件中就无法直接获取。但在 Chrome Extension 或 Puppeteer 自动化框架抓取数据时会遇到这种情况。幸运的是,Chrome Extension 官方提供了相关 API,Puppeteer 也有方法强制开启 Shadow Root。其中,Chrome Extension 可利用 chrome.dom.openOrClosedShadowRoot API,让 Content Script 绕过 Web Component 封装特性访问 closed 状态的 Shadow Root,文中还给出了极简插件示例;Puppeteer 虽无等效 API,但其可通过劫持 Element.prototype.attachShadow 方法,将 closed 模式强制改为 open 来获取数据。
本文于 2025-10-10 12:55 首次发布,最后修改于 2025-10-10 13:20

为了在 封装性 和 可访问性 之间提供不同的权衡,Shadow Root 拥有 openclosed 两种状态。

Shadow Root 两种状态对比
Shadow Root 两种状态对比

在标准的 Shadow DOM 规范中,当一个 Shadow Root 在初始化时设置的是 closed 状态的, 不仅后续无法重新设置为 open 状态,更无法直接获取到该 Shadow Root 实例。这是因为 closed 状态的 Shadow Root 被认为是“不可见”的,“不可见”表现在: 无法使用 element.shadowRoot 直接访问到该 Shadow Root。比如,下面这个页面的 my-component 组件,我们就无法直接获取到 Shadow Root:

标准规范下获取 Shadow Root 结果
标准规范下获取 Shadow Root 结果

如何获取 closed 状态的 Shadow Root?

但当我们在使用 Chrome Extension 或者 Puppeteer 自动化框架抓取数据时,难免会遇到这种情况,那该怎么办呢?

很幸运的是,Chrome Extension 官方就有相关 API 可以直接使用,而 Puppeteer 也可以使用奇技淫巧去强制开启 Shadow Root 来达到目的。

一、Chrome Extension 的 chrome.dom API 方案

Chrome Extension 中 chrome.dom.openOrClosedShadowRoot API 的设计目的就是为了让扩展的 Content Script(内容脚本)能够绕过 Web Component 的封装特性,访问处于 closed 状态的 Shadow Root。

例如,我们可以写一个极简的插件来实现:获取上述 html 中的 internal-span 中的 data-value 属性值

Chrome Extension 获取 closed Shadow Root
Chrome Extension 获取 closed Shadow Root

二、Puppeteer 强制开启 Shadow Root 方案

事实上,Puppeteer 并没有直接提供一个等效于 chrome.dom.openOrClosedShadowRoot 的 API,这是因为它们的工作原理和应用场景有所不同:

  • 浏览器默认行为: 在正常的浏览器环境中,无论是通过页面 JavaScript 还是 Puppeteer 默认的 DOM 查询方法(如 page.$()page.evaluate() 中的 document.querySelector()),都无法访问处于 closed 模式的 Shadow Root。这是 Web Component 规范的安全设计;

  • 扩展权限: Chrome 扩展的 chrome.dom.openOrClosedShadowRoot 是一个特殊的、高权限的 API,它仅在扩展的 Content Script 中可用,用于解决扩展与 Web Component 交互的问题,它超越了标准的 Web 安全模型;

  • Puppeteer 的定位: Puppeteer 主要是一个通过 DevTools Protocol (CDP) 自动化控制 标准浏览器行为 的库。它通常遵循 Web 页面的标准限制。

但是,为了迎合从第三方网站获取一个非公开数据属性的场景,强制开启 Shadow Root(Monkey Patching)仍然是最有效的方法,虽然该方法其实会带来严重的安全性、稳定性问题(一个封闭的 Shadow Root 环境被强制开启 本就是一个危险的操作)。

Puppeteer 获取 closed Shadow Root
Puppeteer 获取 closed Shadow Root

1个赞
喜欢就点个赞吧